﻿using Microsoft.Extensions.Caching.Memory;
using System;
using System.Threading.Tasks;

namespace Qy.Core;
public class MemoryManager : ICacheManager
{
    private readonly IMemoryCache _memoryCache = null;
    private readonly Task CompletedTask = Task.FromResult<object>(null);

    public MemoryManager(IMemoryCache memoryCache)
    {
        _memoryCache = memoryCache ?? throw new ArgumentNullException(nameof(memoryCache));
    }

    public string GetValue(string key)
    {
        try
        {
            return _memoryCache.Get(key)?.ToString();
        }
        catch (Exception)
        {
            return null;
        }
    }
    public Task<string> GetValueAsync(string key)
    {
        try
        {
            _memoryCache.Get(key)?.ToString();
            return (Task<string>)CompletedTask;
        }
        catch (Exception)
        {
            return null;
        }
    }


    public T Get<T>(string key)
    {
        if (key == null)
        {
            throw new ArgumentNullException(nameof(key));
        }
        key = key.ToLower();

        return _memoryCache.Get<T>(key);
    }

    public async Task<T> GetAsync<T>(string key)
    {
        return await Task.FromResult(Get<T>(key));
    }

    public void Remove(string key)
    {
        if (key == null)
        {
            throw new ArgumentNullException(nameof(key));
        }
        key = key.ToLower();
        this._memoryCache.Remove(key);
    }


    public Task RemoveAsync(string key)
    {
        Remove(key);
        return CompletedTask;
    }

    public void Set<T>(string key, T value, TimeSpan timeSpan)
    {
        if (key == null)
        {
            throw new ArgumentNullException(nameof(key));
        }

        if (value == null)
        {
            throw new ArgumentNullException(nameof(value));
        }

        if (!string.IsNullOrEmpty(key) && (value != null))
        {
            key = key.ToLower();
            _memoryCache.Set(key, value, timeSpan);
        }
    }

    public Task SetAsync<T>(string key, T value, TimeSpan timeSpan)
    {
        Set(key, value, timeSpan);
        return CompletedTask;
    }
}
